#ifndef BACKENDSERVICE_H
#define BACKENDSERVICE_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QStringList>
#include <QStandardPaths>
#include <QDir>
#include <QSettings>
#include "databasemanager.h"

class DatabaseManager;

class BackendService : public QObject
{
    Q_OBJECT

public:
    explicit BackendService(QObject *parent = nullptr);
    ~BackendService();

    // 登录检查
    Q_INVOKABLE void loginCheckin(const QString &username, const QString &password, const QString &checkcode = "");
    
    // 保存登录信息
    Q_INVOKABLE void saveLoginInfo(const QString &username, const QString &password);
    
    // 读取登录信息
    Q_INVOKABLE QStringList loadLoginInfo();
    
    // 测试方法：插入测试文件夹数据
    Q_INVOKABLE void insertTestFolderData();
    
    // 同步网盘接口
    Q_INVOKABLE void syncDisks();
    
    // 同步文件夹接口
    Q_INVOKABLE void syncFolders(const QString &diskId);
    
    // 同步文件接口
    Q_INVOKABLE void syncFiles(const QString &diskId, const QString &folderId);
    Q_INVOKABLE void commitFile(const QString &diskId, const QString &folderId, const QString &sourceFileId);
    
    // 选择并上传文件接口
    Q_INVOKABLE void selectAndUploadFile(const QString &folderId);
    
    // 通过文件ID获取KmsFile接口
    Q_INVOKABLE void getKmsFileByFileId(const QString &fileId);
    
    // 下载文件接口
    Q_INVOKABLE void downloadFile(const QString &url, const QString &fileName = "", const QString &fileId = "");
    
    // 回撤文件接口
    Q_INVOKABLE void rollbackFile(const QString &fileId);
    
    // 打开文件接口
    Q_INVOKABLE void openFile(const QString &filePath);
    // 根据文件ID打开文件接口
    Q_INVOKABLE void openFileByFileId(const QString &fileId);
    // 通过URL下载并打开文件接口
    Q_INVOKABLE void openFileByURL(const QString &downloadUrl, const QString &accessToken = "");
    // 获取用户工作目录(work)的本地绝对路径: Home/.myapps/{username}/work
    Q_INVOKABLE QString getUserWorkBaseDir() const;
    
    // 工作台相关接口
    Q_INVOKABLE void getApplications();
    
    // 通知相关接口
    Q_INVOKABLE void getNotice(int readStatus = -1, int type = 0, int currpage = 1, int rowcount = 30);
    Q_INVOKABLE void markReadNotice(const QString &noticeId);
    
    // 获取AccessToken接口
    Q_INVOKABLE void exchangeAccessToken(const QString &domainId);
    
    // 获取domains信息
    Q_INVOKABLE QVariantList getDomains();
    
    // 获取访问令牌
    Q_INVOKABLE QString getAccessToken();
    
    // 设置数据库管理器
    void setDatabaseManager(DatabaseManager *databaseManager);
    
    // 获取数据库管理器
    DatabaseManager* getDatabaseManager() const;
    
    // 保存和加载选中的公司
    Q_INVOKABLE void saveSelectedCompany(const QString &companyId, const QString &companyName);
    Q_INVOKABLE QStringList loadSelectedCompany();
    Q_INVOKABLE void saveSelectedDiskId(const QString &diskId);
    Q_INVOKABLE QString loadSelectedDiskId();
    Q_INVOKABLE QString loadSelectedCompanyId();

signals:
    // 登录结果信号
    void loginResult(int resultCode, const QString &message, const QStringList &domains);
    
    // 用户工作目录创建完成信号
    void userWorkDirectoryCreated(const QString &username, const QString &workDirectory);
    
    // 同步网盘完成信号
    void syncDisksCompleted(int resultCode, const QString &message);
    
    // 网盘数据同步信号（用于更新数据库）
    void syncDisksData(const QJsonArray &disksData);
    
    // 同步文件夹完成信号
    void syncFoldersCompleted(int resultCode, const QString &message);
    
    // 文件夹数据同步信号（用于更新数据库）
    void syncFoldersData(const QJsonArray &foldersData);
    
    // 同步文件完成信号
    void syncFilesCompleted(int resultCode, const QString &message);
    
    // 文件数据同步信号（用于更新数据库）
    void syncFilesData(const QJsonArray &filesData);
    
    // 文件提交完成信号
    void commitFileCompleted(int resultCode, const QString &message);
    
    // 文件提交数据信号（用于更新数据库）
    void commitFileData(const QJsonArray &filesData);
    
    // 文件提交成功信号（用于更新文件状态）
    void commitFileSuccess(const QString &sourceFileId);
    
    // 文件下载完成信号
    void downloadFileCompleted(int resultCode, const QString &message, const QString &filePath);
    
    // 文件下载进度信号
    void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
    
    // 回撤文件完成信号
    void rollbackFileCompleted(int resultCode, const QString &message);
    
    // 文件打开完成信号
    void openFileCompleted(int resultCode, const QString &message);
    
    // 获取KmsFile完成信号
    void getKmsFileByFileIdCompleted(int resultCode, const QString &message, const QVariantMap &fileData);
    
    // 获取AccessToken完成信号
    void exchangeAccessTokenCompleted(int resultCode, const QString &message, const QString &accessToken);
    
    // 工作台相关信号
    void getApplicationsCompleted(int resultCode, const QString &message, const QVariantList &applications);

    // 通知相关信号
    void getNoticeCompleted(int resultCode, const QString &message, const QVariantList &notices);
    void markReadNoticeCompleted(int resultCode, const QString &message, const QString &noticeId);
    void networkError(int errorCode, const QString &errorString);

    // 注意：fileDownloadedForUrl信号已废弃（URL字段已移除），不再使用

private:
    QNetworkAccessManager *m_networkManager;
    QString m_baseUrl;
    QString m_currentUsername; // 当前登录用户名
    QString m_checkInToken; // 登录令牌
    QString m_accessToken; // 访问令牌
    QJsonArray m_domains; // 域名信息
    DatabaseManager *m_databaseManager; // 数据库管理器
    
    // 用于跟踪获取accessToken后需要执行的操作
    QString m_pendingSyncDiskId; // 待同步的网盘ID
    QString m_pendingSyncFolderId; // 待同步的文件夹ID
    QString m_pendingCommitSourceFileId; // 待提交的源文件ID
    
    // 当前提交的文件ID（用于成功后更新状态）
    QString m_currentCommitSourceFileId;
    
    // 处理登录响应
    void handleLoginResponse(QNetworkReply *reply);
    
    // 解析登录响应
    void parseLoginResponse(const QJsonObject &response, const QString &username);
    
    // 创建用户工作目录
    QString createUserWorkDirectory(const QString &username);
    
    // 处理同步网盘响应
    void handleSyncDisksResponse(QNetworkReply *reply);
    
    // 解析同步网盘响应
    void parseSyncDisksResponse(const QJsonObject &response);
    
    // 处理同步文件夹响应
    void handleSyncFoldersResponse(QNetworkReply *reply);
    
    // 解析同步文件夹响应
    void parseSyncFoldersResponse(const QJsonObject &response);
    
    // 处理同步文件响应
    void handleSyncFilesResponse(QNetworkReply *reply);
    
    // 解析同步文件响应
    void parseSyncFilesResponse(const QJsonObject &response);
    
    // 处理获取KmsFile响应
    void handleGetKmsFileResponse(QNetworkReply *reply);
    
    // 解析获取KmsFile响应
    void parseGetKmsFileResponse(const QJsonObject &response);
    
    // 将QVariantMap转换为KmsFile的辅助方法
    KmsFile convertVariantMapToKmsFile(const QVariantMap &fileMap);
    
    // 实际执行打开文件的方法（内部使用）
    void doOpenFileWithKmsFile(const KmsFile &kmsFile);
    
    // 处理文件提交响应
    void handleCommitFileResponse(QNetworkReply *reply);
    
    // 解析文件提交响应
    void parseCommitFileResponse(const QJsonObject &response);
    
    // 处理获取应用列表响应
    void handleGetApplicationsResponse(QNetworkReply *reply);
    
    // 解析获取应用列表响应
    void parseGetApplicationsResponse(const QJsonObject &response);
    
    // 处理文件下载响应
    void handleDownloadFileResponse(QNetworkReply *reply);
    
    // 处理通过URL下载文件响应
    void handleDownloadFileByURLResponse(QNetworkReply *reply);
    
    // 处理回撤文件响应
    void handleRollbackFileResponse(QNetworkReply *reply);
    
    // 处理获取AccessToken响应
    void handleExchangeAccessTokenResponse(QNetworkReply *reply);
    
    // 解析获取AccessToken响应
    void parseExchangeAccessTokenResponse(const QJsonObject &response);
    
    // Token相关方法
    void saveToken(const QString &checkInToken);
    QString loadAccessToken();
    void clearToken();
    void addTokenToRequest(QNetworkRequest &request);
    void ensureAccessToken(const QString &domainId);
    
    // Domains相关方法
    void saveDomains(const QJsonArray &domains);
    QJsonArray loadDomains();
    void clearDomains();
    
    // 选中公司ID和网盘ID的保存和加载
    void saveSelectedCompanyId(const QString &companyId);
    
    // 设置默认公司（当没有保存的公司或保存的公司不在domains中时）
    void setDefaultCompany();
    
    // 设置默认网盘（当没有保存的网盘ID时）
    void setDefaultDisk(const QJsonArray &disksData);
    
    // 通知相关私有方法
    void handleGetNoticeResponse(QNetworkReply *reply);
    void parseGetNoticeResponse(const QJsonObject &response);
    void handleMarkReadNoticeResponse(QNetworkReply *reply);
    void parseMarkReadNoticeResponse(const QJsonObject &response);
    void handleNetworkError(QNetworkReply *reply);
    QNetworkRequest createRequest(const QString &url, const QString &method = "GET");
    QString buildQueryParams(int readStatus, int type, int currpage, int rowcount);
};

#endif // BACKENDSERVICE_H
